﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using HardToolApp.Model;
using HardToolApp.Tool;
using HardToolApp.View;
using Microsoft.Win32;
using NLua;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using static System.Windows.Forms.AxHost;

namespace HardToolApp.ViewModel
{
    
    [ViewModelHelper("脚本", typeof(ScriptPage), typeof(ScriptModel), Sort = 9)]
    public class ScriptVM: PeripheralVM
    {
        public Thread task;
        private bool abort;
        string _btnText = "执行";
        public string BtnText { get=>_btnText; set => SetProperty(ref _btnText , value); }
        public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
        static string _outputText;
        public static string OutputText { get => _outputText;set { _outputText = value; StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(OutputText))); } }
        string _scriptText;
        public string ScriptText { get => _scriptText; set => SetProperty(ref _scriptText,value); }
        public RelayCommand<ScriptModel> ItemCmd { get; set; }
        public RelayCommand DoScript { get; set; }
        public RelayCommand StopScript { get; set; }
        public RelayCommand ClearOutput { get; set; }
        public RelayCommand APIHelp { get; set; }

        public static Lua lua = new Lua();
        public static ObservableCollection<ScriptModel> funs = new ObservableCollection<ScriptModel>();
        
        
        public static void register(string funcName,string param,string typeName, Type t, string note,string res)
        {
            lua.RegisterFunction(funcName, null, t.GetMethod(funcName));
            APIHelper.Add(typeName, funcName, param, res, note);
        }

        private void ItemClick(ScriptModel t)
        {
            ScriptText += "\r\n" + t.funcName;
        }

        private void SriptExc()
        { 
            if(BtnText.Equals("执行"))
            {
                task = new Thread(() =>
                {
                    BtnText = "停止";
                    try
                    {
                        lua.DoString(ScriptText);
                        Console.WriteLine("done");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    BtnText = "执行";
                });
                task.Start();
            }
            else
            {
                abort = true;
                BtnText = "执行";
            }
            
        }

        private void State_DebugHook(object sender, NLua.Event.DebugHookEventArgs e)
        {
            if (abort)
            {
                abort = false;
                Lua l = (Lua)sender;
                l.State.Error("Execution manually aborted");
            }
            //if(e.LuaDebug.Event == KeraLua.LuaHookEvent.Return)
            //{
            //    OutputText += e.LuaDebug.NumberUpValues;
            //}
        }
        public static void debug(string format,params object[] args)
        {
            OutputText += string.Format(format,args);
        }
        public static void delay(int ms)
        {
            Thread.Sleep(ms);
        }
        public ScriptVM()
        {
            register("delay","(时间ms)","Common",GetType(),"延时，有几十毫秒的误差 无法精准延时","空");
            register("debug", "参考C# 的string.Format", "Common", GetType(), "在调试窗口输出", "空");
            lua.SetDebugHook(KeraLua.LuaHookMask.Line|KeraLua.LuaHookMask.Return,1);
            lua.DebugHook += State_DebugHook;
            ItemCmd = new RelayCommand<ScriptModel>(ItemClick);
            DoScript = new RelayCommand(SriptExc);
            ClearOutput = new RelayCommand(() => {OutputText = string.Empty;} );
            APIHelp = new RelayCommand(() => { new APIHelper().Show(); });
        }
    }
}
